SPI 制御による
DAコンバータ出力
(→プロジェクトファイル(Harmony Ver.2.04版 ) ダウンロード)
PIC32MZを使い、SPI モジュールを内臓したマイクロチップのD/AコンバータMCP4922をSPI制御してD/A変換を行った例を紹介します。
<仕様>
・ DAコンバータに正弦波電圧を出力する。
・ PICはPIC32MZ2048EFH100を用い、DAコンバータはMCP4922を用いる。
・ 1度毎の正弦波テーブルを生成し、割り込みによりこのデータを500Hzで(2 msec毎に)サンプリングしてSPI通信でD/Aコンバータ
MCP4922に伝送する。
SPI諸元(PIC側):
モード: マスターモード
SPIクロック周波数: 10MHz
データ幅: 16ビット
データモード: IDLE Low ACTIVE High
遷移: クロックがACTIVE(High) → IDLE(Low)に変化した時、MCP4922レジスタデータ変化
データ抽出タイミング: データの後縁
・ MCP4922(電源電圧+3.3V)からは、1.39Hz(注)、Vp-p 2.7V、分解能12ビットの正弦波電圧を出力する。
出力ポートはVoutAとする。
(注)1.39Hz = 500KHz ÷ 360
・ Harmonyの スタティックSPIライブラリとスタティクタイマライブらを用いる。
<回路図>( → PDFファイル)
<外観>
PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
汎用モジュール評価ボード(段積みボード)には本テーマと関係ない部品が多々実装されています。
DAコンバータ MCP4922の 端子VoutAの出力電圧 |
1V/div 200msec/div |
<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
(以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なることがあるかもしれませんので注意してください。)
■ MHC設定
■ Options
■ Pin Settings
項目 | ⑤ポート設定 |
MHC | |
備考 | デフォルトからの変更要領: RF2/Function: GPIO_OUT (CS用出力ポート設定) RD0/Function: SCK4 (SPI4のSCK設定) RD11/Function: SDO4 (SPI4のSDO設定) |
■ app.cに、青字部分を追加します。
① delay_us( )、delay_ms( ) という NOPを使った 1μsec 、1msec単位の遅延関数をつくります。
void delay_us(volatile unsigned int usec) //1μsec遅延
{
volatile int count;
……
……
② 正弦波形出力のテーブル作成用の関数を作成します。
void SinTable() //Sin のテーブル作成
{
short int i;
float PAI = 3.1416;
……
……
③ APP_Initialize ( )の中で、 Sin波形のテーブルを作成後、インターバルタイマの割り込みを許可します。
SinTable();
DRV_TMR0_Start(); //必須
以下、app.c
■ system_interrupt.c に 青字部分を追加します。
①割り込みハンドラの中に割り込み時の処理を記述します。
デフォルトでインターバルタイマが選択されているので下記の(タイマ再書き込みの)記述は必要ありません。
PLIB_TMR_Period16BitSet(TMR_ID_1,25000); //5 nsec x2 x 25000 x 8 =
10000nsec = 1000μsec = 2msec
②DAコンバータ MCP4922のCSを LOW("0")にセットします。
LATFbits.LATF2 = 0; //MCP4922 CS = 0
③SPIモジュールに所要の16ビット信号を書き込んで、書き込みが完了するまで待ちます。
更にMCP4922での処理が完了するまで待ちます。
PLIB_SPI_BufferWrite16bit(SPI_ID_4,(short int)(sinValue[angleValue]
| 0b0001000000000000)); //送信データ送信
// SPI4BUF = (short int)(sinValue[angleValue] |
0b0001000000000000); //送信データ送信
//MP4922 制御コマンド
//VoutAにゲイン2で出力
//MCP4922への書き込みコマンド
//bit15(書き込みレジスタ選択) 1:VoutB 0:VoutA
//bit14(予備)
//bit13(出力ゲイン選択) 1:1倍 0:2倍
//bit12(出力オフ制御) 1:出力ON 0:出力OFF
//bit11-bit0 データ MSBから順次送信される
while(PLIB_SPI_TransmitBufferIsFull(SPI_ID_4)); //SPI4SRレジスタへの書込み完了
// while(SPI4STATbits.SPITBF); //: SPI Transmit Buffer Full Status
bit //SPI4SRレジスタへの書込み完了
delay_us(20); //MCP4922の処理待ち
④ 角度を1度インクリメントします。 1周期(360度)になったら0度に戻します。
angleValue++;
if(angleValue >= 360)angleValue = 0;
⑤ DAコンバータ MCP4922のCSを HIGH("1")にセットします。
LATFbits.LATF2 = 1; //MCP4922 CS = 1;
以下、System_interrupt.c